package no.awi.wpd.combat.model;

import static no.awi.wpd.probability.ProbabilityDistribution.ZERO;

import no.awi.wpd.probability.ProbabilityDistribution;
import no.awi.wpd.unit.model.Profile;
import no.awi.wpd.unit.model.TroopType;
import no.awi.wpd.unit.model.Unit;

import java.util.*;

/**
 * An {@link ContactZone} is a set of models, from a single unit, that have
 * the same chosen attackable opponent.
 */
public class ContactZone {

	private ContactZone attackableOpponent;
    
	private int modelsInBaseContact;
	
	private Unit unit;
	
	private ProbabilityDistribution woundsTaken = ZERO();

    private List<AttackStep> attackSteps;
	
	public ContactZone() {
	    // Empty
	}

    public ContactZone(ContactZone attackableOpponent, int modelsInBaseContact, Unit unit) {
        super();
        this.attackableOpponent = attackableOpponent;
        this.modelsInBaseContact = modelsInBaseContact;
        this.unit = unit;
    }

    public ContactZone getAttackableOpponent() {
        return attackableOpponent;
    }

    public void setAttackableOpponent(ContactZone attackableOpponent) {
        this.attackableOpponent = attackableOpponent;
    }

    public int getModelsInBaseContact() {
        return modelsInBaseContact;
    }

    public void setModelsInBaseContact(int modelsInBaseContact) {
        this.modelsInBaseContact = modelsInBaseContact;
    }

    public Unit getUnit() {
        return unit;
    }

    public void setUnit(Unit unit) {
        this.unit = unit;
    }

    public ProbabilityDistribution getWoundsTaken() {
        return woundsTaken;
    }

    public void setWoundsTaken(ProbabilityDistribution woundsTaken) {
        this.woundsTaken = woundsTaken;
    }
    
    public void addWoundsTaken(ProbabilityDistribution woundsTaken) {
        ProbabilityDistribution result = this.woundsTaken.add(woundsTaken)
                .withMaxValue(unit.getModelCount() * unit.getProfile().getWo());
        setWoundsTaken(result);
    }

    public List<AttackStep> getAttackSteps() {
        List<AttackStep> result = new ArrayList<AttackStep>();
        result.add(new AttackStep(this, unit.getProfile()));
        if (unit.getMount() != null) {
            result.add(new AttackStep(this, unit.getMount()));
        }
        ProbabilityDistribution stomp = TroopType.stomp(unit.getProfile().getType(), attackableOpponent.getUnit()
                .getProfile().getType());
        if (!stomp.equals(ZERO())) {
            Profile stompProfile = unit.getMount() != null ? unit.getMount() : unit.getProfile();
            result.add(new AttackStep(this, stompProfile, InitiativeStep.ASL, stomp));
        }
        return result;
    }

    public int getNumberOfWounds() {
        return unit.getProfile().getWo() * unit.getModelCount();
    }
}
